import React from "react";
import { connect } from 'react-redux'
import { Button, Icon, message, Row } from 'antd';
import GraphicReportService from "./graphic-report.service";
import 'styles/data-center/report/graphic-report/index.scss';
import { messages } from "share/common";
import errorMessage from 'share/errorMessage';

import ReportPrivateService from "./report-private.service"
import AdvancedSearch from "components/advanced-search";

function mapStateToProps(state) {
  const { currentMenuPermission = {} } = state.main;
  const { tenant, company } = state.login;
  const { currentActiveKey = [] } = currentMenuPermission;
  const currentRoute = currentActiveKey[currentActiveKey.length - 1];
  return {
    company,
    tenant,
    currentRoute,
  }
}

@connect(mapStateToProps)
class GraphicReport extends React.Component {
  advancedSearchRef = {};
  advancedSearchFormRef = {};
  currentReportPrivate = undefined;

  state = {
    isFetchingData: false,
    searchParams: {},//搜索参数
    activeChartsParams: {}, // 用于保存点击报表产生的params，不直接修改searchParams是为了能够回退
    searchForm: [],//搜索组件
    reportConfig: {},
    isPreview: false,
    reportId: undefined,
  }

  constructor(props) {
    super(props);
    let reportId = props.params.id;
    // this.currentReportPrivate = ReportPrivateService[reportId];
    this.state.reportId = reportId;
    // this.state.reportConfig = this.currentReportPrivate.reportConfig(this);
  }

  componentDidMount() {
    const { currentRoute } = this.props;
    this.setState({
      isPreview: currentRoute === 'graphic-report-preview',
    });
    this.InitReportConfig();
    this.InitSearchComponents();
  }

  componentWillReceiveProps(nextProps){
    if(this.props.params != nextProps.params){
      this.state.reportId = nextProps.params.id;
      this.advancedSearchRef.reset()
      this.InitReportConfig();
      this.InitSearchComponents();
    }
  }

  //初始化搜索组件
  InitSearchComponents = () => {
    let searchForm = GraphicReportService.InitSearchComponents({ context: this });
    this.setState({
      searchForm
    }, () => {
      this.advancedSearchRef && this.advancedSearchRef.search();
    })
  }

  // 初始化报表配置
  InitReportConfig() {
    this.currentReportPrivate = ReportPrivateService[this.state.reportId];
    let orginReportConfig= this.state.reportConfig || {}
    this.state.reportConfig = this.currentReportPrivate.reportConfig(this);
    for(let key in orginReportConfig){
      let config= orginReportConfig[key];
      if(config.isTable && config.ref){
        for(let subKey in this.state.reportConfig){
          let subConfig= this.state.reportConfig[subKey]
          if(subConfig.isTable){
            this.state.reportConfig[subKey].ref= config.ref
          }
        }
      }
    }
  }

  getAnalysisReport = () => {
    let { searchParams } = this.state;

    GraphicReportService.searchParamsTransfer({ params: searchParams, context: this })
      .then((res) => {
        res.reportId = this.props.params.id;
        this.clearAllActiveItem();
        this.setState({ transParams: res }, () => this.getAnalysisReportAction(res, undefined));
      })
      .catch((err) => {
        if (err && err.type === 'validateError') {
          message.warn(err.message);
        } else {
          errorMessage(err ? err.response : err)
        }
      })
  }

  //点击搜索
  handleSearch = (values) => {
    //账套单独处理
    this.setState({
      searchParams: values,
    }, () => {
      this.getAnalysisReport();
    })
  };


  onChartClick = ({ item, chartIndex, reportKey, active }) => {
    let criteria = null;
    let { searchParams, reportConfig, activeChartsParams } = this.state;
    let params = { ...searchParams };
    let currentConfig = reportConfig[reportKey];
    const activeConfig = currentConfig.activeConfig;
    const targetKey = activeConfig.key;

    /**
     * 点击激活时，需要将当前项的criteria赋值给params
     * 失效时回退
     *
     * activeChartsParams用于记录已激活项产生的params修改
     *
     * activeConfig的key为string时直接赋值
     * 为对象时表示该对象的属性均要赋值给params
     * array属性表示要将当前值放在数组中（因为原筛选项是多选的）
     */
    if (!active) {
      if (typeof targetKey === 'object') {
        for (let key in targetKey) {
          params[key] = searchParams[key];
          activeChartsParams[key] = undefined;
        }
      } else {
        params[targetKey] = searchParams[targetKey];
        activeChartsParams[targetKey] = undefined;
      }
    } else {
      criteria = item.data.criteria;
      if (typeof targetKey === 'object') {
        for (let key in targetKey) {
          let isArray = targetKey[key].array;
          if (isArray) {
            params[key] = [criteria[key]];
            activeChartsParams[key] = [criteria[key]];
          } else {
            params[key] = criteria[key];
            activeChartsParams[key] = criteria[key];
          }
        }
      } else {
        let isArray = activeConfig.array;
        if (isArray) {
          params[targetKey] = [criteria];
          activeChartsParams[targetKey] = [criteria];
        } else {
          params[targetKey] = criteria;
          activeChartsParams[targetKey] = criteria;
        }
      }
    }

    params = Object.assign(params, activeChartsParams);
    this.setState({
      activeChartsParams
    });
    GraphicReportService.searchParamsTransfer({ params, context: this })
      .then((res) => {
        res.reportId = this.props.params.id;
        this.getAnalysisReportAction(res, reportKey);
      })
      .catch((err) => {
        if (err && err.type === 'validateError') {
          message.warn(err.message);
        } else {
          errorMessage(err ? err.response : err)
        }
      })
  };

  /**
   *
   * @param searchParams  查询参数
   * @param triggerType 点击图表的类型 没有则表示是搜索或清空搜索
   */
  getAnalysisReportAction = (searchParams, triggerType) => {
    const { reportConfig, isPreview } = this.state;
    searchParams.preview = isPreview;
    let allType = Object.keys(reportConfig);

    if (triggerType) {
      allType = allType.filter(type => type !== triggerType);
    }

    allType.forEach(type => {
      let currentConfig = reportConfig[type] || {};
      currentConfig.isLoading = true;
    });


    let promiseList = new Promise(resolve => {
      setTimeout(() => {
        resolve(Promise.all(allType.map(type => {
          try {
            return this.getSpecificReportData(type, searchParams, triggerType)
          } catch (e) {
            console.error(e);
            return Promise.resolve()
          }
        })))
      })
    });

    this.setState({
      isFetchingData: true,
      reportConfig
    });

    promiseList.catch(e => {
      errorMessage(e);
    }).finally(() => {
      this.setState({
        isFetchingData: false
      })
    });
  };

  getSpecificReportData = (type, params, triggerType) => {
    let isClickChart = !!triggerType;
    let { reportConfig, searchParams } = this.state;
    let currentConfig = reportConfig[type] || {};
    let { fetchMethod = () => Promise.resolve(), ref, isTable } = currentConfig;
    if (isTable) {
      fetchMethod = ref.fetchList
    }
    /**
     * 点击图表时，忽略当前点击项的搜索值
     *
     * 为什么要这么做，因为点击当前图表是不需要重新加载当前图表的数据的
     *
     * 不需要加载当前图表，这一步其实在getAnalysisReportAction中的allType.filter(type => type !== triggerType)就已经完成了
     * 这里做的事其实是，当有其他的图表的activeConfig.key也就是查询字段和被点击的图表一样时，该图表也忽略点击项的搜索值
     * 但我翻了目前的所有报表，没有哪个报表有两个一样的activeConfig.key
     * 唯一一个有的是合规明细图表，而这个恰好不希望有相同key的图表忽略点击项的搜索值，所以加了一个activeConfig.notReset
     */
    if (isClickChart) {
      const activeConfig = currentConfig.activeConfig || {};
      const targetKey = activeConfig.key;
      const targetNotReset = activeConfig.notReset || false

      if (targetKey && !targetNotReset) {
        let resetObject = {};
        if (typeof targetKey === 'object') {
          for (let key in targetKey) {
            resetObject[key] = searchParams[key];
          }
        } else {
          resetObject[targetKey] = searchParams[targetKey];
        }
        params = Object.assign({}, params, resetObject);
      }
    }

    // 拦截并处理params
    if (this.currentReportPrivate.fetchInterceptor) {
      params = this.currentReportPrivate.fetchInterceptor(params);
    }

    return fetchMethod(params).then((res) => {
      currentConfig.isLoading = false;
      if (res && !isTable) {
        currentConfig.options = res.options;
        currentConfig.dataLength = res.dataLength;
      }
      return res;
    }, (err) => {
      currentConfig.isLoading = false;
      throw err
    }).finally(() => {
      this.setState(
        reportConfig
      );
    })
  };

  onMountCharts = ({ ref, reportKey }) => {
    let { reportConfig } = this.state;
    reportConfig[reportKey].ref = ref;
    this.setState({
      reportConfig
    })
  };

  clearAllActiveItem() {
    let { reportConfig } = this.state;
    for (let key in reportConfig) {
      let { ref } = reportConfig[key];
      ref && ref.clearActiveItem && ref.clearActiveItem();
    }
    this.setState({
      activeChartsParams: {}
    });
  };

  //返回到列表
  handleBack = () => {
    window.history.go(-1);
  };

  onChangePinnedList = pinnedList => {
    this.setState({ pinnedList });
  };

  render() {
    const {
      reportConfig,
      searchForm,
      pinnedList
    } = this.state;
    let reportName = this.props.params.reportName || messages('finance-7.key170')/*报表详情*/;
    let reportTypes = Object.keys(reportConfig);
    let context = this;
    return (
      <div className="graphic-report-container">
        <div className="search-wrapper">
          <AdvancedSearch
            onSearch={this.handleSearch}
            title={reportName}
            onRef={ref => this.advancedSearchRef = ref}
            getForm={form => this.advancedSearchFormRef = form}
            searchForm={searchForm}
            pinnedList={pinnedList}
            onChangePinnedList={this.onChangePinnedList}
            tableName={`graphic-report-${this.props.params.id}`}
            notLoadWhenMount
          />
        </div>
        <Row className='graphic-report-inner-wrap' type="flex">
          {reportTypes.map(reportType => {
            let config = reportConfig[reportType] || {
              render: () => {
              }
            };
            return config.render({ config, context, reportType })
          })}
        </Row>
        <div className='new-bottom-back'>
          <Button onClick={this.handleBack}>{messages('common.back')/*返回*/}</Button>
        </div>
      </div>
    )
  }
}

export default GraphicReport;
